package cn.jingyuan.bee.utils.collection;

import java.io.Serializable;
import java.util.Iterator;
import java.util.List;

/**
 * 复制 {@link Iterator}<br>
 * 为了解决并发情况下 {@link Iterator} 遍历导致的问题（当 Iterator 被修改会抛出 ConcurrentModificationException），故使用复制原 Iterator 的方式解决此问题
 *
 * <p>
 * 解决方法为：在构造方法中遍历 Iterator 中的元素，装入新的 List 中然后遍历之。
 * 当然，修改这个复制后的 Iterator 是没有意义的，因此 remove 方法将会抛出异常。
 *
 * <p>
 * 需要注意的是，在构造此对象时需要保证原子性（原对象不被修改），最好加锁构造此对象，构造完毕后解锁。
 *
 * @param <E> 元素类型
 */
public class CopiedIter<E> implements Iterator<E>, Iterable<E>, Serializable {

    private final Iterator<E> listIterator;

    /**
     * 构造
     *
     * @param iterator 被复制的 Iterator
     */
    public CopiedIter(Iterator<E> iterator) {
        final List<E> eleList = CollectionUtils.newArrayList(iterator);
        this.listIterator = eleList.iterator();
    }

    public static <V> CopiedIter<V> copyOf(Iterator<V> iterator) {
        return new CopiedIter<>(iterator);
    }

    @Override
    public boolean hasNext() {
        return this.listIterator.hasNext();
    }

    @Override
    public E next() {
        return this.listIterator.next();
    }

    /**
     * 此对象不支持移除元素
     *
     * @throws UnsupportedOperationException 当调用此方法时始终抛出此异常
     */
    @Override
    public void remove() throws UnsupportedOperationException {
        throw new UnsupportedOperationException("This is a read-only iterator.");
    }

    @Override
    public Iterator<E> iterator() {
        return this;
    }

}
